'''
$LastChangedBy: csgillespie $
$LastChangedDate: 2007-06-06 11:08:06 +0000 (Wed, 06 Jun 2007) $
Colin Gillespie (c.gillespie@ncl.ac.uk)

Imported into the BASISTools function
'''

import libsbml

class AddSBML:
	'''Used to add elements to the SBML model.Called in BASISTools
	'''
	
	def __init__(self, model, sbml_parts, alter_dict):
		self.m = model
		self.sbml_parts = sbml_parts
		self.alter_dict = alter_dict
			
	def alterModel(self):
		'''Alter the SBML'''
		for part in self.sbml_parts:
			getattr(self, 'add'+part)()
		return 1
		
	def addCompartments(self):
		'''Adds a compartment to the model'''
		if not self.alter_dict['Co']:
			return 0
		new_cp = self.m.createCompartment()
		for key, value in self.alter_dict['Co'].items():
			getattr(new_cp, 'set'+key)(value)
		return 1

	def addSpecies(self):
		'''Adds a specie to the model'''
		if not self.alter_dict['Sp']:
			return 0
		new_sp = self.m.createSpecies()
		for key, value in self.alter_dict['Sp'].items():
			getattr(new_sp, 'set'+key)(value)
		return 1

	def addParameters(self):
		'''Adds a global parameter to the model'''
		if not self.alter_dict['Pa']:
			return 0
		new_pa = self.m.createParameter()
		for key, value in self.alter_dict['Pa'].items():
			getattr(new_pa, 'set'+key)(value)
		return 1

	def addReactions(self):
		'''Adds a reaction to the model'''
		if not self.alter_dict['Re']:
			return 0
		new_re = self.m.createReaction()
		for key, value in self.alter_dict['Re'].items():
			if key in ['listOfReactants', 'listOfProducts', 'listOfModifiers']:
				self.__addSpeciesReference(key, value)
			elif key == 'KineticLaw':
				self.__addKineticLaw(value)
			else:
				getattr(new_re, 'set'+key)(value)
		return 1
	
	def __addSpeciesReference(self, type_of, parameters):
		'''Determines if the species is a Rectant/Product/Modifier
		then adds the species to the reaction'''
		for species_attributes in parameters:
		#Create a new species - listOf[6:-1] just returns Reactant/Product/Modifier
			new_species = getattr(self.m, 'create' + type_of[6:-1])()
			for key, attribute in species_attributes.items():
				getattr(new_species, 'set'+key)(attribute)

	def __addKineticLaw(self, parameters):
		'''adds the KL and local parameters to the reaction'''
		new_kinetic_law = self.m.createKineticLaw()
		formula = str(parameters['Formula'])
		new_kinetic_law.setFormula(formula)
		new_kinetic_law.setMathFromFormula()
		local_parameters = parameters.get('listOfParameters', [])
		for local_parameter in local_parameters:
			new_pa = libsbml.Parameter()
			for key, value in local_parameter.items():
				getattr(new_pa, 'set' + key)(value)
			new_kinetic_law.addParameter(new_pa)

	def addEvents(self):
		'''Adds a event to the model''' 
		if not self.alter_dict['Ev']:
			return 0
		new_ev = self.m.createEvent()
		for key, value in self.alter_dict['Ev'].items():
			if key == 'Trigger':
				self.__addTrigger(new_ev)
			elif key == 'listOfEventAssignments':
				self.__addEventAssignment()
			else:
				getattr(new_ev, 'set'+key)(value)
			
	def __addTrigger(self, event):
		'''Adds a trigger to the event'''
		to_ast_node = libsbml.parseFormula(self.alter_dict['Ev']['Trigger'])
		event.setTrigger(to_ast_node)
		return 1
	
	def __addEventAssignment(self):
		'''Adds all the EAs to the event'''
		event_assignments = self.alter_dict['Ev']['listOfEventAssignments']
		for event_assignment in event_assignments:
			new_ev_assignment = self.m.createEventAssignment()
			variable = event_assignment['Variable']
			new_ev_assignment.setVariable(variable)
			
			formula = str(event_assignment['Formula'])
			new_ev_assignment.setMath(libsbml.parseFormula(formula))
